// /src/app/index.js
'use strict';

const express = require('express');
const config = require('./config');
const { logger, emailTool } = require('./utils');
const { color } = require('./utils/logger.utils'); // 直接从 logger.utils 导入 color
const { connectDatabase } = require('../database/connection');
const { errorMiddleware, securityMiddleware } = require('./middleware'); // 全局异常处理中间件
const resourceMonitor = require('./utils/resource.monitor');
const app = express();

// 中间件配置
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(securityMiddleware);
const separator = '='.repeat(60);
const ALERT_EMAILS = config.environment.alert.receiveEmails.split(',');
const NODE_ENV = config.environment.nodeEnv;

// 新增：系统未捕获异常告警（进程级）
process.on('uncaughtException', (err) => {
    logger.error(`${color.red}❌ 系统未捕获异常：${err.message}${color.reset}`, { metadata: {} });
    logger.error(`堆栈：${err.stack}`, { metadata: {} });

    if (NODE_ENV === 'production') {
        const alertContent = `
            <p>🚨 [紧急] CorpHR系统未捕获异常（进程即将退出）</p>
            <p>时间：${new Date().toLocaleString()}</p>
            <p>环境：${NODE_ENV}</p>
            <p>错误详情：${err.message}</p>
            <p>错误堆栈：${err.stack.substring(0, 800)}${err.stack.length > 800 ? '...' : ''}</p>
            <p>影响：系统进程即将崩溃，服务中断</p>
            <p>解决方案：紧急排查异常代码，重启服务</p>
        `;
        ALERT_EMAILS.forEach((email) => {
            emailTool
                .sendNotice(email, '[紧急] CorpHR系统未捕获异常告警', alertContent)
                .catch((mailErr) =>
                    logger.error(`❌ 未捕获异常告警邮件发送失败：${mailErr.message}`, { metadata: {} }),
                );
        });
    }
    process.exit(1);
});

// 新增：Promise未捕获拒绝告警
process.on('unhandledRejection', (reason, promise) => {
    logger.error(`${color.red}❌ Promise未捕获拒绝：${reason.message || reason}${color.reset}`, { metadata: {} });
    logger.error(`Promise：${promise}`, { metadata: {} });

    if (NODE_ENV === 'production') {
        const alertContent = `
            <p>🚨 [重要] CorpHR系统Promise未捕获拒绝</p>
            <p>时间：${new Date().toLocaleString()}</p>
            <p>环境：${NODE_ENV}</p>
            <p>错误详情：${reason.message || reason}</p>
            <p>Promise：${JSON.stringify(promise, null, 2)}</p>
            <p>影响：可能导致部分功能异常，内存泄漏</p>
            <p>解决方案：检查异步代码的catch处理</p>
        `;
        ALERT_EMAILS.forEach((email) => {
            emailTool
                .sendNotice(email, '[重要] CorpHR Promise未捕获拒绝告警', alertContent)
                .catch((mailErr) => logger.error(`❌ Promise告警邮件发送失败：${mailErr.message}`, { metadata: {} }));
        });
    }
});

// 新增：进程退出告警
process.on('exit', (code) => {
    if (code !== 0) {
        logger.error(`${color.red}❌ 系统进程异常退出，退出码：${code}${color.reset}`, { metadata: {} });
        if (NODE_ENV === 'production') {
            const alertContent = `
                <p>🚨 [紧急] CorpHR系统进程异常退出</p>
                <p>时间：${new Date().toLocaleString()}</p>
                <p>环境：${NODE_ENV}</p>
                <p>退出码：${code}</p>
                <p>影响：服务中断，无法提供功能</p>
                <p>解决方案：紧急重启服务，查看日志排查原因</p>
            `;
            ALERT_EMAILS.forEach((email) => {
                emailTool
                    .sendNotice(email, '[紧急] CorpHR系统进程异常退出告警', alertContent)
                    .catch((mailErr) =>
                        logger.error(`❌ 进程退出告警邮件发送失败：${mailErr.message}`, { metadata: {} }),
                    );
            });
        }
    }
});

/**
 * 异步启动主函数
 */
const bootstrap = async () => {
    try {
        // 启动时初始化邮件服务
        const emailInitResult = await emailTool.initTransporter();
        if (emailInitResult) {
            logger.info(`${color.green}📧 邮件服务初始化成功${color.reset}`, { metadata: {} });
        } else {
            logger.error(`${color.red}❌ 邮件服务初始化失败，告警功能不可用${color.reset}`, { metadata: {} });
        }

        // 1. 系统初始化日志
        logger.info(separator, { metadata: {} });
        logger.info(`${color.bold}🚀  CorpHR 企业人力资源管理系统 - 初始化中${color.reset}`, { metadata: {} });
        logger.info(separator, { metadata: {} });

        // 2. 启动资源监控（生产环境）
        if (NODE_ENV === 'production') {
            resourceMonitor.start();
            logger.info(
                `${color.blue}📊  资源监控已启动（内存阈值：${config.environment.alert.memoryThreshold}%，磁盘阈值：${config.environment.alert.diskThreshold}%）${color.reset}`,
                { metadata: {} },
            );
        }

        // 3. 数据库连接
        const dbResult = await connectDatabase();

        // 4. 构建服务信息
        const serverInfo = [
            {
                label: '运行环境',
                value: `${color.bold}${color.green}${NODE_ENV.toUpperCase()}${color.reset}`,
            },
            { label: 'Node.js 版本', value: process.version },
            {
                label: '服务器地址',
                value: `${color.bold}${color.blue}http://127.0.0.1:${config.server.port}${color.reset}`,
            },
            { label: 'API 基础路径', value: '/api/v1' },
            { label: '日志存储目录', value: config.logger.dir },
            {
                label: '数据库状态',
                value: dbResult.success
                    ? `${color.bold}${color.green}✅ 已连接${color.reset}`
                    : `${color.bold}${color.red}❌ 连接失败${color.reset}`,
            },
            { label: '日志级别', value: config.logger.level.toUpperCase() },
            { label: '服务启动时间', value: new Date().toLocaleString() },
            { label: '数据库类型', value: 'MySQL' },
            { label: '连接地址', value: `${config.database.host}:${config.database.port}` },
            { label: '目标数据库', value: config.database.database },
            { label: '连接耗时', value: `${color.blue}${dbResult.totalCost}ms${color.reset}` },
            { label: '连接池状态', value: `${color.blue}${dbResult.poolStatus}${color.reset}` },
            { label: '数据库重试次数', value: `${color.blue}${dbResult.retryCount}次${color.reset}` },
        ];

        // 5. 输出服务信息
        logger.info(separator, { metadata: {} });
        logger.info(`${color.bold}📋  核心服务信息${color.reset}`, { metadata: {} });
        const maxLabelLength = Math.max(...serverInfo.map((item) => item.label.length));
        serverInfo.forEach(({ label, value }) => {
            const alignedLabel = label.padEnd(maxLabelLength, ' ');
            logger.info(`${alignedLabel}: ${value}`, { metadata: {} });
        });

        logger.info(separator, { metadata: {} });

        // 6. 环境差异化提示
        const yellow = color.yellow || '\u001B[33m';
        if (NODE_ENV === 'production') {
            logger.info(`${color.bold}${yellow}⚠️  生产环境注意事项：${color.reset}`, { metadata: {} });
            logger.info(
                `  1. 已启用日志轮转（单文件${config.logger.rotate.maxSize}，保留${config.logger.rotate.maxFiles}）`,
                { metadata: {} },
            );
            logger.info('  2. 禁止暴露敏感配置，建议通过环境变量注入', { metadata: {} });
            logger.info(`  3. 已启用资源监控和异常告警，告警接收邮箱：${ALERT_EMAILS.join(', ')}`, { metadata: {} });
            logger.info(`  4. 请确保防火墙已开放 ${config.server.port} 端口`, { metadata: {} });
        } else {
            logger.info(`${color.bold}${color.blue}💡 开发环境提示：${color.reset}`, { metadata: {} });
            logger.info('  1. 调试日志已启用，可查看详细请求/数据库日志', { metadata: {} });
            logger.info('  2. 代码修改将自动重启服务（nodemon）', { metadata: {} });
            logger.info(
                `  3. 访问 ${color.bold}${color.blue}http://127.0.0.1:${config.server.port}/api/v1/health${color.reset} 检查服务健康状态`,
                { metadata: {} },
            );
        }

        logger.info(separator, { metadata: {} });

        // 7. 启动服务器
        app.listen(config.server.port, () => {
            logger.info(`${color.bold}${color.green}🎉  CorpHR 企业人力资源管理系统 - 启动成功${color.reset}`, {
                metadata: {},
            });
            logger.info(`${color.bold}${color.green}📡  服务已监听端口：${config.server.port}${color.reset}`, {
                metadata: {},
            });
            logger.info(separator, { metadata: {} });

            // 生产环境：启动成功通知
            if (NODE_ENV === 'production') {
                const alertContent = `
                    <p>✅ CorpHR系统启动成功</p>
                    <p>时间：${new Date().toLocaleString()}</p>
                    <p>环境：${NODE_ENV}</p>
                    <p>服务器地址：http://127.0.0.1:${config.server.port}</p>
                    <p>数据库状态：已连接</p>
                    <p>日志级别：${config.logger.level.toUpperCase()}</p>
                `;
                ALERT_EMAILS.forEach((email) => {
                    emailTool
                        .sendNotice(email, '[正常] CorpHR系统启动成功通知', alertContent)
                        .catch((mailErr) =>
                            logger.error(`❌ 启动成功通知邮件发送失败：${mailErr.message}`, { metadata: {} }),
                        );
                });
            }
        });
    } catch (error) {
        // 启动失败告警
        const alertContent = `
            <p>🚨 [紧急] CorpHR系统启动失败</p>
            <p>时间：${new Date().toLocaleString()}</p>
            <p>环境：${NODE_ENV}</p>
            <p>错误详情：${error.message}</p>
            <p>错误堆栈：${error.stack.substring(0, 800)}${error.stack.length > 800 ? '...' : ''}</p>
            <p>影响：服务无法提供，所有功能不可用</p>
            <p>解决方案：根据错误详情排查配置/依赖问题</p>
        `;
        ALERT_EMAILS.forEach((email) => {
            emailTool
                .sendNotice(email, '[紧急] CorpHR系统启动失败告警', alertContent)
                .catch((mailErr) => logger.error(`❌ 启动失败告警邮件发送失败：${mailErr.message}`, { metadata: {} }));
        });

        // 原有错误日志
        logger.error(`${color.bold}${color.red}💥  系统启动失败：${error.message}${color.reset}`, { metadata: {} });
        logger.error(`堆栈：${error.stack}`, { metadata: {} });
        process.exit(1);
    }
};

// 注册全局异常中间件（必须在路由之后）
app.use(errorMiddleware);

// 执行启动流程
bootstrap();

module.exports = app;
